<template>
  <div class="calendar-warp">
    <div class="calendar-right-panel">
      <div class="calendar-right-header">
        {{ checkDay.year }}年{{ checkDay.month }}月
      </div>
      <div class="calendar-right-date">
        {{ checkDay.date }}
      </div>
      <div class="calendar-right-row">
        {{ checkDay.lunar.IMonthCn }} {{ checkDay.lunar.IDayCn }}
      </div>
      <div class="calendar-right-row">
        {{ checkDay.lunar.gzYear }}【{{ checkDay.lunar.Animal }}年】
      </div>
      <div class="calendar-right-row">
        {{ checkDay.lunar.gzMonth }}月 {{ checkDay.lunar.gzDay }}日
      </div>
      <div class="calendar-right-festival">
        <span v-for="(item,i) in getFestival(checkDay.lunar)" :key="i" class="calendar-festival-tag">
          {{ item.name }}
        </span>
      </div>
      <div v-show="!isToday(checkDay)" class="calendar-back-today" @click="backToday(today)">今</div>
    </div>
    <div class="calendar-left-panel">
      <div class="calendar-header">
        {{ lunar.cYear }}年{{ lunar.cMonth }}月{{ lunar.cDay }}日 {{ lunar.ncWeek }} 农历 {{ lunar.gzYear }}【{{ lunar.Animal }}年】{{ lunar.IMonthCn }} {{ lunar.IDayCn }}
        <span class="calendar-time-tag">{{ hour | fmtTime }}:</span>
        <span class="calendar-time-tag">{{ minutes | fmtTime }}:</span>
        <span class="calendar-time-tag">{{ seconds | fmtTime }}</span>
      </div>
      <div class="calendar-container">
        <table class="calendar-table">
          <thead>
            <tr>
              <td>
                <span class="iconfont icon-left" @click="prevMonth" />
              </td>
              <td colspan="5">
                {{ year }}年{{ month }}月
              </td>
              <td>
                <span class="iconfont icon-right" @click="nextMonth" />
              </td>
            </tr>
            <tr>
              <td v-for="(item,i) in weekMap" :key="i">{{ item }}</td>
            </tr>
          </thead>
          <tbody>
            <tr v-for="(week,i) in views" :key="i">
              <td v-for="(item,j) in week" :key="j">
                <div
                  class="calendar-date-cell"
                  :class="className(item)"
                  @click="selectDate(item)"
                >
                  <span v-if="getHolidayMark(item.lunar).label" class="calendar-tag" :class="getHolidayMark(item.lunar).className">
                    {{ getHolidayMark(item.lunar).label }}
                  </span>
                  <div class="calendar-solar-text">
                    {{ item.date }}
                  </div>
                  <div class="calendar-lunar-text">
                    <template v-if="getFestival(item.lunar).length>0">
                      {{ getFestival(item.lunar)[0].name }}
                    </template>
                    <template v-else>
                      {{ item.lunar.lDay===1?item.lunar.IMonthCn:item.lunar.IDayCn }}
                    </template>
                  </div>
                </div>
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>
  </div>
</template>

<script>
import calendar from '../../../components/calendar'
export default {
  name: 'Calendar',
  filters: {
    fmtTime(value) {
      if (value <= 9) {
        return '0' + value
      }
      return value
    }
  },
  data() {
    return {
      weekMap: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'],
      views: [],
      year: 0,
      month: 0,
      date: 0,
      today: {
        year: 0,
        month: 0,
        date: 0
      },
      checkDay: {
        year: 0,
        month: 0,
        date: 0,
        lunar: {}
      },
      festival: {
        lunar: {
          '1-1': '春节',
          '1-15': '元宵节',
          '2-2': '龙头节',
          '5-5': '端午节',
          '7-7': '七夕节',
          '7-15': '中元节',
          '8-15': '中秋节',
          '9-9': '重阳节',
          '10-1': '寒衣节',
          '10-15': '下元节',
          '12-8': '腊八节',
          '12-23': '祭灶节'
        },
        solar: {
          '1-1': '元旦',
          '2-14': '情人节',
          '3-8': '妇女节',
          '3-12': '植树节',
          '4-4': '清明节',
          '5-1': '劳动节',
          '5-4': '青年节',
          '6-1': '儿童节',
          '7-1': '建党节',
          '8-1': '建军节',
          '9-10': '教师节',
          '10-1': '国庆节',
          '12-24': '平安夜',
          '12-25': '圣诞节'
        }
      },
      dateMarks: [
        // 2020元旦
        { date: ['2020-1-1'], type: 'rest', label: '休', className: 'rest-tag' },
        // 2020春节
        { date: '[2020-1-19]', type: 'work', label: '班', className: 'work-tag' },
        { date: ['2020-1-24', '2020-1-30'], type: 'rest', label: '休', className: 'rest-tag' },
        { date: '[2020-2-1]', type: 'work', label: '班', className: 'work-tag' },
        // 2020清明节
        { date: ['2020-4-4', '2020-4-6'], type: 'rest', label: '休', className: 'rest-tag' },
        { date: ['2020-4-26'], type: 'work', label: '班', className: 'work-tag' },
        // 2020劳动节
        { date: ['2020-5-1', '2020-5-5'], type: 'rest', label: '休', className: 'rest-tag' },
        { date: ['2020-5-9'], type: 'work', label: '班', className: 'work-tag' },
        // 2020端午节
        { date: ['2020-6-25', '2020-6-27'], type: 'rest', label: '休', className: 'rest-tag' },
        { date: ['2020-6-28'], type: 'work', label: '班', className: 'work-tag' },
        // 2020国庆节和中秋节
        { date: ['2020-09-27'], type: 'work', label: '班', className: 'work-tag' },
        { date: ['2020-10-01', '2020-10-08'], type: 'rest', label: '休', className: 'rest-tag' },
        { date: ['2020-10-10'], type: 'work', label: '班', className: 'work-tag' },
        // 2021年元旦
        { date: ['2021-1-1', '2021-1-3'], type: 'rest', label: '休', className: 'rest-tag' },
        //  2021年春节
        { date: ['2021-2-7'], type: 'work', label: '班', className: 'work-tag' },
        { date: ['2021-2-11', '2021-2-17'], type: 'rest', label: '休', className: 'rest-tag' },
        { date: ['2021-2-20'], type: 'work', label: '班', className: 'work-tag' },
        //  2021年清明节
        { date: ['2021-4-3', '2021-4-5'], type: 'rest', label: '休', className: 'rest-tag' },
        //  2021年劳动节
        { date: ['2021-4-25'], type: 'work', label: '班', className: 'work-tag' },
        { date: ['2021-5-1', '2021-5-5'], type: 'rest', label: '休', className: 'rest-tag' },
        { date: ['2021-5-8'], type: 'work', label: '班', className: 'work-tag' },
        //  2021年端午节
        { date: ['2021-6-12', '2021-6-14'], type: 'rest', label: '休', className: 'rest-tag' },
        //  2021年中秋节
        { date: ['2021-9-18'], type: 'work', label: '班', className: 'work-tag' },
        { date: ['2021-9-19', '2021-9-21'], type: 'rest', label: '休', className: 'rest-tag' },
        //  2021年国庆节
        { date: ['2021-9-26'], type: 'work', label: '班', className: 'work-tag' },
        { date: ['2021-10-1', '2021-10-7'], type: 'rest', label: '休', className: 'rest-tag' },
        { date: ['2021-10-9'], type: 'work', label: '班', className: 'work-tag' }
      ],
      holidayPlans: [],
      lunar: {},
      hour: 0,
      minutes: 0,
      seconds: 0
    }
  },
  computed: {
    className() {
      const _this = this
      return (date) => {
        const classname = []
        const mark = _this.getHolidayMark(date.lunar)
        const today = _this.today
        const checkDay = _this.checkDay
        if (date.month === _this.month) {
          classname.push('calendar-cur-month')
        } else {
          classname.push('calendar-near-month')
        }
        if (_this.getFestival(date.lunar).length > 0) {
          classname.push('calendar-has-festival')
        }
        if (date.day === 0 || date.day === 6) {
          classname.push('calendar-weekend')
        }
        if (mark.type === 'rest') {
          classname.push('calendar-rest-date')
        }
        if (mark.type === 'work') {
          classname.push('calendar-work-date')
        }
        if ((date.month === today.month && date.year === today.year && date.date === today.date)) {
          classname.push('calendar-today')
        }
        if ((date.month === checkDay.month && date.year === checkDay.year && date.date === checkDay.date)) {
          classname.push('calendar-checkDay')
        }
        return classname.join(' ')
      }
    }
  },
  created() {
    const now = new Date()
    const year = now.getFullYear()
    const month = now.getMonth() + 1
    const date = now.getDate()
    const lunar = calendar.solar2lunar(year, month, date)
    this.views = this.getMonthView(year, month)
    this.year = year
    this.month = month
    this.date = date
    this.today = { year, month, date }
    this.lunar = lunar
    this.checkDay = {
      year,
      month,
      date,
      lunar
    }
    this.refreshTime()
    setInterval(() => {
      this.refreshTime()
    }, 1000)
    const plansJson = localStorage.getItem('HOLIDAY_PLANS')
    const plans = [{ 'name': '元旦', 'date': '2021-1-1', 'restDays': ['2021-1-1', '2021-1-2', '2021-1-3'], 'workDays': [], 'id': 1620793802487 }, { 'name': '春节', 'date': '2021-2-12', 'restDays': ['2021-2-11', '2021-2-12', '2021-2-13', '2021-2-14', '2021-2-15', '2021-2-16', '2021-2-17'], 'workDays': ['2021-2-7', '2021-2-20'], 'id': 1620793818841 }, { 'name': '清明节', 'date': '2021-4-4', 'restDays': ['2021-4-3', '2021-4-4', '2021-4-5'], 'workDays': [], 'id': 1620793825871 }, { 'name': '劳动节', 'date': '2021-5-1', 'restDays': ['2021-5-1', '2021-5-2', '2021-5-3', '2021-5-4', '2021-5-5'], 'workDays': ['2021-4-25', '2021-5-8'], 'id': 1620793834315 }, { 'name': '端午节', 'date': '2021-6-14', 'restDays': ['2021-6-12', '2021-6-13', '2021-6-14'], 'workDays': [], 'id': 1620793840142 }, { 'name': '中秋节', 'date': '2021-9-21', 'restDays': ['2021-9-19', '2021-9-20', '2021-9-21'], 'workDays': ['2021-9-18'], 'id': 1620793844938 }, { 'name': '国庆节', 'date': '2021-10-1', 'restDays': ['2021-10-1', '2021-10-2', '2021-10-3', '2021-10-4', '2021-10-5', '2021-10-6', '2021-10-7'], 'workDays': ['2021-9-26', '2021-10-9'], 'id': 1620793854781 }, { 'name': '元旦', 'date': '2020-1-1', 'restDays': ['2020-1-1'], 'workDays': [], 'id': 1620793962443 }, { 'name': '春节', 'date': '2020-1-25', 'restDays': ['2020-1-24', '2020-1-25', '2020-1-26', '2020-1-27', '2020-1-28', '2020-1-29', '2020-1-30'], 'workDays': ['2020-1-19', '2020-2-1'], 'id': 1620793968404 }, { 'name': '清明节', 'date': '2020-4-4', 'restDays': ['2020-4-4', '2020-4-5', '2020-4-6'], 'workDays': [], 'id': 1620793971998 }, { 'name': '劳动节', 'date': '2020-5-1', 'restDays': ['2020-5-1', '2020-5-2', '2020-5-3', '2020-5-4', '2020-5-5'], 'workDays': ['2020-4-26', '2020-5-9'], 'id': 1620793976140 }, { 'name': '端午节', 'date': '2020-6-25', 'restDays': ['2020-6-25', '2020-6-26', '2020-6-27'], 'workDays': ['2020-6-28'], 'id': 1620793981411 }, { 'name': '中秋&国庆', 'date': '2020-10-1', 'restDays': ['2020-10-1', '2020-10-2', '2020-10-3', '2020-10-4', '2020-10-5', '2020-10-6', '2020-10-7', '2020-10-8'], 'workDays': ['2020-9-27', '2020-10-10'], 'id': 1620793987430 }]
    if (plansJson) {
      this.holidayPlans = JSON.parse(plansJson)
    } else {
      this.holidayPlans = plans
    }
  },
  methods: {
    getMonthView(year, month) {
      const firstDate = new Date(year, month - 1, 1, 0, 0, 0, 0)
      const oneDay = 24 * 3600 * 1000
      const firstViewDate = new Date(firstDate - (firstDate.getDay() * oneDay))
      const viewsDate = []
      let week = []
      for (let i = 0; i < 42; i++) {
        const item = new Date(firstViewDate.getTime() + (i * oneDay))
        const day = item.getDay()
        const dateCell = {
          year: item.getFullYear(),
          month: item.getMonth() + 1,
          date: item.getDate(),
          day: item.getDay(),
          lunar: calendar.solar2lunar(item.getFullYear(), (item.getMonth() + 1), item.getDate())
        }
        week.push(dateCell)
        if (week.length > 7) {
          week.shift()
        }
        if (day === 6) {
          viewsDate.push(week)
          week = []
        }
      }
      return viewsDate
    },
    getFestival(lunar) {
      const festival = {
        lunar: '',
        solar: ''
      }
      if (this.festival.lunar[lunar.lMonth + '-' + lunar.lDay]) {
        festival.lunar = this.festival.lunar[lunar.lMonth + '-' + lunar.lDay]
      }
      if (this.festival.solar[lunar.cMonth + '-' + lunar.cDay]) {
        festival.solar = this.festival.solar[lunar.cMonth + '-' + lunar.cDay]
      }
      const list = []
      if (festival.lunar) {
        list.push({ name: festival.lunar, type: 'lunar' })
      }
      if (festival.solar) {
        list.push({ name: festival.solar, type: 'solar' })
      }
      return list
    },
    getDateMark(lunar) {
      const dateTime = new Date(lunar.cYear, (lunar.cMonth - 1), lunar.cDay, 0, 0, 0, 0).getTime()
      let dateMark = {}
      function transformDate(str) {
        const arr = str.split('-')
        return new Date(Number(arr[0]), (Number(arr[1]) - 1), Number(arr[2]), 0, 0, 0, 0)
      }
      this.dateMarks.forEach((item) => {
        const arr = item.date
        if (arr.length === 1) {
          const itemTime = transformDate(arr[0]).getTime()
          if (itemTime === dateTime) {
            dateMark = item
          }
        }
        if (arr.length === 2) {
          const minTime = transformDate(arr[0]).getTime()
          const maxTime = transformDate(arr[1]).getTime()
          if (dateTime >= minTime && dateTime <= maxTime) {
            dateMark = item
          }
        }
      })
      return dateMark
    },
    refreshTime() {
      const now = new Date()
      const year = now.getFullYear()
      const month = now.getMonth() + 1
      const date = now.getDate()
      const today = this.today
      this.hour = now.getHours()
      this.minutes = now.getMinutes()
      this.seconds = now.getSeconds()
      this.lunar = calendar.solar2lunar(year, month, date)
      if (!(today.date === date && today.month === month && today.year === year)) {
        this.today = { year, month, date }
        this.year = year
        this.month = month
        this.date = date
        this.views = this.getMonthView(year, month)
      }
    },
    nextMonth() {
      const next = this.month + 1
      if (next > 12) {
        this.year += 1
        this.month = 1
      } else {
        this.month = next
      }
      this.views = this.getMonthView(this.year, this.month)
    },
    prevMonth() {
      const prev = this.month - 1
      if (prev < 1) {
        this.year -= 1
        this.month = 12
      } else {
        this.month = prev
      }
      this.views = this.getMonthView(this.year, this.month)
    },
    selectDate(item) {
      const day = Object.assign({}, item)
      const { year, month, date } = day
      this.checkDay = day
      if (day.month !== this.month || day.year !== this.year) {
        this.year = year
        this.month = month
        this.date = date
        this.views = this.getMonthView(year, month)
      }
    },
    backToday(today) {
      const { year, month, date } = today
      const lunar = calendar.solar2lunar(year, month, date)
      this.year = year
      this.month = month
      this.date = date
      this.views = this.getMonthView(year, month)
      this.checkDay = {
        year,
        month,
        date,
        lunar
      }
    },
    isToday(day) {
      return day.year === this.year && day.month === this.today.month && day.date === this.today.date && day.month === this.month
    },
    getHolidayMark(lunar) {
      const marks = {}
      this.holidayPlans.forEach((item) => {
        const { restDays, workDays } = item
        restDays.forEach((rest) => {
          marks[rest] = { date: rest, type: 'rest', label: '休', className: 'rest-tag' }
        })
        workDays.forEach((work) => {
          marks[work] = { date: work, type: 'work', label: '班', className: 'work-tag' }
        })
      })
      const sDate = lunar.cYear + '-' + lunar.cMonth + '-' + lunar.cDay
      if (marks[sDate]) {
        return marks[sDate]
      } else {
        return {}
      }
    }
  }
}
</script>

<style scoped>
  .calendar-warp{
    display: block;
    background-color: #ffffff;
    left: 40px;
    top: 40px;
    height: 437px;
    width: 560px;
  }
  .calendar-warp:after{
    display: table;
    content: '';
    clear: both;
  }
  .calendar-left-panel{
    margin-right: 120px;
    height: 100%;
    padding: 10px;
    border-top: 2px solid #4E6EF2;
    border-left: 2px solid #4E6EF2;
    border-bottom: 2px solid #4E6EF2;
    box-sizing: border-box;
  }
  .calendar-right-panel{
    width: 120px;
    background-color: #4E6EF2;
    height: 100%;
    float: right;
    position: relative;
  }
  .calendar-table{
    width: 100%;
    border-collapse: collapse;
    border-spacing:0;
  }
  .calendar-table thead td{
    text-align: center;
    line-height: 28px;
    font-size: 14px;
    color: #3a3c3e;
    font-weight: 500;
    border-spacing:0;
  }
  .calendar-table thead td span{
    cursor: pointer;
  }
  .calendar-table td{
    border: 1px solid transparent;
  }
  .calendar-date-cell{
    min-width: 50px;
    height: 40px;
    padding: 5px 0;
    position: relative;
    border-radius: 2px;
  }
  .calendar-tag{
    position: absolute;
    left: 2px;
    top: 2px;
    font-size: 12px;
  }
  .calendar-solar-text{
    font-size: 16px;
    line-height: 20px;
    text-align: center;
  }
  .calendar-lunar-text{
    font-size: 12px;
    line-height: 20px;
    text-align: center;
    text-overflow: ellipsis;
    overflow: hidden;
    white-space: nowrap;
  }
  .calendar-cur-month .calendar-solar-text{
    color: #3a3c3e;
  }
  .calendar-cur-month .calendar-lunar-text{
    color: #606266;
  }
  .calendar-near-month .calendar-solar-text{
    color: #a9afb5;
  }
  .calendar-near-month .calendar-lunar-text{
    color: #a9afb5;
  }
  .calendar-cur-month.calendar-has-festival .calendar-lunar-text{
    color: #F73131;
  }
  .calendar-cur-month.calendar-weekend .calendar-solar-text{
    color: #F73131;
  }
  .rest-tag{
    color: #F73131;
  }
  .work-tag{
    color: #8f8d93;
  }
  .calendar-cur-month.calendar-work-date .calendar-solar-text{
    color: #3a3c3e;
  }
  .calendar-cur-month:hover{
    background-color: #f2f2f2;
    cursor: pointer;
  }
  .calendar-cur-month.calendar-rest-date{
    background-color: rgba(247, 49, 49,0.15);
  }
  .calendar-cur-month.calendar-work-date{
    background-color: #f2f2f2;
  }
  .calendar-cur-month.calendar-today{
    background-color: rgba(0, 37, 154, 0.15);
  }
  .calendar-cur-month.calendar-checkDay{
    background-color: rgba(46, 138, 224, 0.15);
  }
  .calendar-header{
    font-size: 14px;
    color: #3a3c3e;
    line-height: 30px;
    padding: 0 10px;
    word-wrap: normal;
    white-space: nowrap;
  }
  .calendar-time-tag{
    display: inline-block;
    width: 22px;
    text-align: center;
    font-size: 14px;
  }
  .calendar-time-tag:last-child{
    text-align: left;
  }
  .calendar-right-header{
    text-align: center;
    font-size: 14px;
    line-height: 30px;
    color: #f2f2f2;
    padding-top: 10px;
  }
  .calendar-right-date{
    display: block;
    width: 80px;
    height: 80px;
    font-size: 52px;
    text-align: center;
    line-height: 80px;
    margin: 15px auto;
    background-color: rgba(255, 255, 255, 0.5);
    border-radius: 12px;
    color: #f2f2f2;
  }
  .calendar-right-row{
    text-align: center;
    font-size: 14px;
    color: #f2f2f2;
    line-height: 20px;
  }
  .calendar-right-festival{
    line-height: 20px;
    padding: 0 10px;
    margin-top: 5px;
  }
  .calendar-festival-tag{
    display: inline-block;
    font-size: 12px;
    line-height: 20px;
    color: #f2f2f2;
    margin-right: 3px;
  }
  .calendar-festival-tag:before{
    display: inline-block;
    content: '•';
  }
  .calendar-back-today{
    width: 50px;
    height: 50px;
    position: absolute;
    background-color: #e64b15;
    border-radius: 50%;
    left: 50%;
    margin-left: -25px;
    line-height: 50px;
    text-align: center;
    font-size: 30px;
    color: #f2f2f2;
    bottom: 30px;
    cursor: pointer;
  }
</style>
